package view.panel;

import tool.DisableEditTableModel;
import view.dialog.DepartmentDialog;

import javax.swing.*;

import bean.Department;
import bean.Employee;
import dao.DepartmentDAO;
import dao.EmployeeDAO;
import dao.UserDAO;

import java.awt.*;
import java.awt.event.*;
import java.sql.Connection;
import java.sql.Date;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.*;

public class EmployeePanel extends JPanel {
    private static final long serialVersionUID = -3383993935798675681L;
    private DepartmentDAO departmentDAO;
    private EmployeeDAO employeeDAO;
    private UserDAO userDAO;
    private Dimension dimension;
    private SimpleDateFormat format;
    private Hashtable<Integer, String> departmentData;
    private Set<Map.Entry<Integer, String>> departmentDataEntrySet;
    private JPanel leftPanel;
    private JPanel northPanel;
    private JTextField queryIdTextField;
    private JTextField queryKeywordTextField;
    private JComboBox<String> queryDepartment;
    private DefaultComboBoxModel<String> queryComboBoxModel;
    private JButton query;
    private JScrollPane scrollPane;
    private JTable table;
    private DisableEditTableModel tableModel;
    private JPanel southPanel;
    private JButton editEmployeeButton;
    private JButton addEmployeeButton;
    private JButton deleteEmployeeButton;
    private JPanel rightPanel;
    private JPanel panel1, panel2, panel3, panel4, panel5, panel6, panel7, panel8, panel9;
    private JTextField employeeIdTextField;
    private JTextField employeeNameTextField;
    private JComboBox<String> departmentsComboBox;
    private DefaultComboBoxModel<String> comboBoxModel;
    private ButtonGroup buttonGroup;
    private ButtonModel maleButtonModel;
    private ButtonModel femaleButtonModel;
    private JRadioButton maleRadioButton;
    private JRadioButton femaleRadioButton;
    private JTextField birthdateTextField;
    private JTextField telephoneTextField;
    private JTextArea addressTextArea;
    private JTextField enrollmentDateTextField;
    private JButton submitButton;
    private JButton manageDepartmentButton;

    public EmployeePanel(Connection conn) throws SQLException {
        super(new BorderLayout());
        userDAO = new UserDAO(conn);
        departmentDAO = new DepartmentDAO(conn);
        employeeDAO = new EmployeeDAO(conn);
        setName("员工管理");
        dimension = new Dimension(83, 22);
        format = new SimpleDateFormat("yyyy-MM-dd");
        comboBoxItems();
        leftPanel = new JPanel(new BorderLayout());
        add(leftPanel);
        northPanel = new JPanel();
        northPanel.add(new JLabel("员工编号"));
        queryIdTextField = new JTextField();
        queryIdTextField.setPreferredSize(dimension);
        queryIdTextField.addFocusListener(new FocusListener() {
            @Override
            public void focusGained(FocusEvent focusEvent) {}

            @Override
            public void focusLost(FocusEvent focusEvent) {
                JTextField source = (JTextField) focusEvent.getComponent();
                String employeeId = source.getText();
                if (Objects.nonNull(employeeId) && employeeId.length() > 0) {
                    queryKeywordTextField.setText(null);
                    queryDepartment.setSelectedIndex(0);
                }
            }
        });
        northPanel.add(queryIdTextField);
        northPanel.add(new JLabel("员工关键字"));
        queryKeywordTextField = new JTextField();
        queryKeywordTextField.setPreferredSize(dimension);
        queryKeywordTextField.addFocusListener(new FocusListener() {
            @Override
            public void focusGained(FocusEvent focusEvent) {}

            @Override
            public void focusLost(FocusEvent focusEvent) {
                JTextField source = (JTextField) focusEvent.getComponent();
                String employeeKeyword = source.getText();
                if (Objects.nonNull(employeeKeyword) && employeeKeyword.length() > 0) {
                    queryIdTextField.setText(null);
                }
            }
        });
        northPanel.add(queryKeywordTextField);
        northPanel.add(new JLabel("所属部门"));
        queryDepartment = new JComboBox<>();
        queryDepartment.setPreferredSize(dimension);
        queryDepartment.addItemListener(itemEvent -> {
            if (itemEvent.getStateChange() == ItemEvent.SELECTED) {
                queryIdTextField.setText(null);
            }
        });
        northPanel.add(queryDepartment);
        query = new JButton("查询员工");
        query.addActionListener(actionEvent -> {
            String queryId = queryIdTextField.getText();
            try {
                // 通过员工编号查询
                if (Objects.nonNull(queryId) && queryId.length() > 0) {
                    int employeeId = Integer.parseInt(queryId);
                    tableModel.setDataVector(getRowsData(employeeId), columnNames());
                } else {
                    // 通过员工关键字及所属部门查询
                    String keyword = queryKeywordTextField.getText();
                    String departmentName = (String) queryDepartment.getSelectedItem();
                    int departmentId = 0;
                    for (Map.Entry<Integer, String> entry : departmentDataEntrySet) {
                        if (entry.getValue().equals(departmentName)) {
                            departmentId = entry.getKey();
                            break;
                        }
                    }
                    tableModel.setDataVector(getRowsData(keyword, departmentId), columnNames());
                }
            String employeeIdText = employeeIdTextField.getText();
            if (Objects.nonNull(employeeIdText) && employeeIdText.length() > 0) {
                employeeIdTextField.setText(null);
                employeeNameTextField.setText(null);
                departmentsComboBox.setSelectedIndex(0);
                maleRadioButton.setEnabled(true);
                femaleRadioButton.setEnabled(true);
                birthdateTextField.setText(null);
                telephoneTextField.setText(null);
                addressTextArea.setText(null);
                enrollmentDateTextField.setText(null);
                enrollmentDateTextField.setEnabled(true);
            }
            if (queryDepartment.getSelectedIndex() == 0) {
                comboBoxItems();
                addItemsToComboBoxes();
            }
            } catch (NumberFormatException e) {
                JOptionPane.showMessageDialog(null, "员工编号不是纯数字");
                queryIdTextField.requestFocusInWindow();
                queryIdTextField.selectAll();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        });
        northPanel.add(query);
        leftPanel.add(northPanel, BorderLayout.NORTH);
        scrollPane = new JScrollPane();
        table = new JTable();
        scrollPane.setViewportView(table);
        tableModel = new DisableEditTableModel();
        table.setModel(tableModel);
        tableModel.setDataVector(getRowsData(null, 0), columnNames());
        leftPanel.add(scrollPane, BorderLayout.CENTER);
        southPanel = new JPanel();
        editEmployeeButton = new JButton("编辑员工");
        editEmployeeButton.addActionListener(actionEvent -> {
            int length = table.getSelectedRows().length;
            if (length == 1) {
                int employeeId = (int) tableModel.getValueAt(table.getSelectedRow(), 0);
                try {
                    Employee employee = employeeDAO.selectById(employeeId);
                    employeeIdTextField.setText(String.valueOf(employee.getEmployeeId()));
                    employeeNameTextField.setText(employee.getEmployeeName());
                    departmentsComboBox.setSelectedItem(getRowsData(employee.getEmployeeId()).get(0).get(2));
                    if (employee.getSex().equals("男")) {
                        buttonGroup.setSelected(maleButtonModel, true);
                    } else {
                        buttonGroup.setSelected(femaleButtonModel, true);
                    }
                    maleRadioButton.setEnabled(false);
                    femaleRadioButton.setEnabled(false);
                    birthdateTextField.setText(format.format(employee.getBirthdate()));
                    telephoneTextField.setText(employee.getTelephone());
                    addressTextArea.setText(employee.getAddress());
                    enrollmentDateTextField.setText(format.format(employee.getEnrollmentDate()));
                    enrollmentDateTextField.setEnabled(false);
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        });
        southPanel.add(editEmployeeButton);
        addEmployeeButton = new JButton("添加员工");
        addEmployeeButton.addActionListener(actionEvent -> {
            table.clearSelection();
            employeeIdTextField.setText(null);
            employeeNameTextField.setText(null);
            departmentsComboBox.setSelectedIndex(0);
            maleRadioButton.setEnabled(true);
            femaleRadioButton.setEnabled(true);
            birthdateTextField.setText(null);
            telephoneTextField.setText(null);
            addressTextArea.setText(null);
            enrollmentDateTextField.setText(null);
            enrollmentDateTextField.setEnabled(true);
        });
        southPanel.add(addEmployeeButton);
        deleteEmployeeButton = new JButton("删除员工");
        deleteEmployeeButton.addActionListener(actionEvent -> {
            int[] rows = table.getSelectedRows();
            try {
                if (rows.length > 0) {
                    int state = JOptionPane.showConfirmDialog(null, "确定要删除选中的员工信息吗？此操作不可逆。", "确认删除", JOptionPane.YES_NO_OPTION);
                    if (state == 0) {
                        // 倒序删除员工
                        for (int rowIndex = rows.length - 1; rowIndex > -1; rowIndex--) {
                            int employeeId = (int) tableModel.getValueAt(rows[rowIndex], 0);
                            int userId = userDAO.selectIdByEmployeeId(employeeId);
                            JPanel cardPanel = (JPanel) getParent();
                            UserPanel userPanel = (UserPanel) cardPanel.getComponent(4);
                            if (userId > 0 && userPanel.getUserId() != userId) {
                                // 先从用户数据库表中删除与此员工编号关联的用户
                                userDAO.delete(userId);
                                // 再从员工数据库表中删除此员工
                                employeeDAO.delete(employeeId);
                                // 更新员工表格模型
                                tableModel.removeRow(rows[rowIndex]);
                                JPanel leftPanel = (JPanel) userPanel.getComponent(0);
                                JScrollPane scrollPane = (JScrollPane) leftPanel.getComponent(0);
                                JTable table = (JTable) scrollPane.getViewport().getView();
                                DisableEditTableModel tableModel = (DisableEditTableModel) table.getModel();
                                for (int index = 0; index < tableModel.getRowCount(); index++) {
                                    int id = (int) tableModel.getValueAt(index, 0);
                                    if (id == userId) {
                                        tableModel.removeRow(index);
                                        break;
                                    }
                                }
                            }
                        }
                        JOptionPane.showMessageDialog(null, "除已登录的用户编号关联的员工信息不能被删除外，其他员工及其被关联的用户信息均可以被删除");
                        String employeeIdText = employeeIdTextField.getText();
                        if (Objects.nonNull(employeeIdText) && employeeIdText.length() > 0) {
                            employeeIdTextField.setText(null);
                            employeeNameTextField.setText(null);
                            departmentsComboBox.setSelectedIndex(0);
                            maleRadioButton.setEnabled(true);
                            maleButtonModel = maleRadioButton.getModel();
                            buttonGroup.setSelected(maleButtonModel, true);
                            femaleRadioButton.setEnabled(true);
                            birthdateTextField.setText(null);
                            telephoneTextField.setText(null);
                            addressTextArea.setText(null);
                            enrollmentDateTextField.setText(null);
                            enrollmentDateTextField.setEnabled(true);
                        }
                    }
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        });
        southPanel.add(deleteEmployeeButton);
        leftPanel.add(southPanel, BorderLayout.SOUTH);
        rightPanel = new JPanel(new GridLayout(9, 1));
        rightPanel.add(new JPanel());
        panel1 = (JPanel) rightPanel.getComponent(0);
        panel1.add(new JLabel("员工编号"));
        employeeIdTextField = new JTextField();
        employeeIdTextField.setPreferredSize(dimension);
        employeeIdTextField.setEnabled(false);
        panel1.add(employeeIdTextField);
        rightPanel.add(new JPanel());
        panel2 = (JPanel) rightPanel.getComponent(1);
        panel2.add(new JLabel("员工姓名"));
        employeeNameTextField = new JTextField();
        employeeNameTextField.setPreferredSize(dimension);
        panel2.add(employeeNameTextField);
        rightPanel.add(new JPanel());
        panel3 = (JPanel) rightPanel.getComponent(2);
        panel3.add(new JLabel("所属部门"));
        departmentsComboBox = new JComboBox<>();
        departmentsComboBox.setPreferredSize(dimension);
        panel3.add(departmentsComboBox);
        rightPanel.add(new JPanel());
        panel4 = (JPanel) rightPanel.getComponent(3);
        panel4.add(new JLabel("员工性别"));
        buttonGroup = new ButtonGroup();
        maleRadioButton = new JRadioButton("男");
        maleButtonModel = maleRadioButton.getModel();
        femaleRadioButton = new JRadioButton("女");
        femaleButtonModel = femaleRadioButton.getModel();
        buttonGroup.add(maleRadioButton);
        buttonGroup.add(femaleRadioButton);
        buttonGroup.setSelected(maleButtonModel, true);
        panel4.add(maleRadioButton);
        panel4.add(femaleRadioButton);
        rightPanel.add(new JPanel());
        panel5 = (JPanel) rightPanel.getComponent(4);
        panel5.add(new JLabel("员工出生日期"));
        birthdateTextField = new JTextField();
        birthdateTextField.setPreferredSize(dimension);
        panel5.add(birthdateTextField);
        rightPanel.add(new JPanel());
        panel6 = (JPanel) rightPanel.getComponent(5);
        panel6.add(new JLabel("员工电话"));
        telephoneTextField = new JTextField();
        telephoneTextField.setPreferredSize(dimension);
        panel6.add(telephoneTextField);
        rightPanel.add(new JPanel());
        panel7 = (JPanel) rightPanel.getComponent(6);
        panel7.add(new JLabel("员工住址"));
        addressTextArea = new JTextArea();
        addressTextArea.setPreferredSize(new Dimension(125, 51));
        addressTextArea.setLineWrap(true);
        panel7.add(addressTextArea);
        rightPanel.add(new JPanel());
        panel8 = (JPanel) rightPanel.getComponent(7);
        panel8.add(new JLabel("员工入职日期"));
        enrollmentDateTextField = new JTextField();
        enrollmentDateTextField.setPreferredSize(dimension);
        panel8.add(enrollmentDateTextField);
        rightPanel.add(new JPanel());
        panel9 = (JPanel) rightPanel.getComponent(8);
        submitButton = new JButton("提交");
        submitButton.addActionListener(actionEvent -> {
            try {
                String employeeIdText = employeeIdTextField.getText();
                String employeeName = employeeNameTextField.getText();
                String departmentName = (String) departmentsComboBox.getSelectedItem();
                int departmentId = 0;
                for (Map.Entry<Integer, String> entry : departmentDataEntrySet) {
                    if (entry.getValue().equals(departmentName)) {
                        departmentId = entry.getKey();
                        break;
                    }
                }
                boolean sex = maleRadioButton.isSelected();
                String sexText = sex ? "男" : "女";
                Date birthdate = Date.valueOf(birthdateTextField.getText());
                String telephone = telephoneTextField.getText();
                String address = addressTextArea.getText();
                Date enrollmentDate = Date.valueOf(enrollmentDateTextField.getText());
                boolean employeeNameState = Objects.nonNull(employeeName) && employeeName.length() > 0;
                boolean birthdateState = Objects.nonNull(birthdate);
                boolean telephoneState = Objects.nonNull(telephone) && telephone.length() > 0;
                boolean addressState = Objects.nonNull(address) && address.length() > 0;
                boolean enrollmentDateState = Objects.nonNull(enrollmentDate);
                boolean state = employeeNameState && birthdateState && telephoneState && addressState && enrollmentDateState;
                Employee employee = new Employee(employeeName, departmentId, sexText, birthdate, telephone, address, enrollmentDate);
                if (!state) {
                    JOptionPane.showMessageDialog(null, "员工信息的部分字段的内容为空，请填写完整");
                } else if (Objects.nonNull(employeeIdText) && employeeIdText.length() > 0) {
                    // 编辑员工
                    int employeeId = Integer.parseInt(employeeIdTextField.getText());
                    state = employeeDAO.update(employeeId, employee);
                    if (state) {
                        JOptionPane.showMessageDialog(null, "编辑员工信息成功");
                        employeeIdTextField.setText(null);
                        maleRadioButton.setEnabled(true);
                        femaleRadioButton.setEnabled(true);
                        enrollmentDateTextField.setEnabled(true);
                    } else {
                        JOptionPane.showMessageDialog(null, "编辑员工信息失败");
                    }
                } else {
                    // 添加员工
                    state = employeeDAO.insert(employee);
                    if (state) {
                        JOptionPane.showMessageDialog(null, "添加员工信息成功");
                    }
                    else {
                        JOptionPane.showMessageDialog(null, "添加员工信息失败");
                    }
                }
                if (state) {
                    comboBoxItems();
                    addItemsToComboBoxes();
                    queryIdTextField.setText(null);
                    queryKeywordTextField.setText(null);
                    queryDepartment.setSelectedIndex(0);
                    tableModel.setDataVector(getRowsData(null, 0), columnNames());
                    employeeNameTextField.setText(null);
                    departmentsComboBox.setSelectedIndex(0);
                    maleButtonModel = maleRadioButton.getModel();
                    buttonGroup.setSelected(maleButtonModel, true);
                    birthdateTextField.setText(null);
                    telephoneTextField.setText(null);
                    addressTextArea.setText(null);
                    enrollmentDateTextField.setText(null);
                }
            } catch (SQLException e) {
                e.printStackTrace();
            } catch (IllegalArgumentException e) {
                JOptionPane.showMessageDialog(null, "员工出生日期或员工入职日期格式错误");
            }
        });
        panel9.add(submitButton);
        manageDepartmentButton = new JButton("管理部门");
        manageDepartmentButton.addActionListener(actionEvent -> {
            try {
                DepartmentDialog dialog = new DepartmentDialog(conn);
                dialog.setVisible(true);
                dialog.addWindowListener(new WindowAdapter() {
                    @Override
                    public void windowClosed(WindowEvent windowEvent) {
                        try {
                            comboBoxItems();
                            addItemsToComboBoxes();
                        } catch (SQLException e) {
                            e.printStackTrace();
                        }
                    }
                });
            } catch (SQLException | ClassNotFoundException e) {
                e.printStackTrace();
            }
        });
        panel9.add(manageDepartmentButton);
        add(rightPanel, BorderLayout.EAST);
        addItemsToComboBoxes();
    }

    private Vector<String> comboBoxItems() throws SQLException {
        departmentData = new Hashtable<>();
        Vector<Department> departments = departmentDAO.selectAll();
        for (Department department : departments) {
            int departmentId = department.getDepartmentId();
            String departmentName = department.getDepartmentName();
            departmentData.put(departmentId, departmentName);
        }
        Vector<String> items = new Vector<>();
        departmentDataEntrySet = departmentData.entrySet();
        for (Map.Entry<Integer, String> entry : departmentDataEntrySet) {
            String departmentName = entry.getValue();
            items.addElement(departmentName);
        }
        return items;
    }

    private void addItemsToComboBoxes() throws SQLException {
        comboBoxModel = new DefaultComboBoxModel<>(comboBoxItems());
        departmentsComboBox.setModel(comboBoxModel);
        Vector<String> items = comboBoxItems();
        items.add(0, "未指定");
        queryComboBoxModel = new DefaultComboBoxModel<>(items);
        queryDepartment.setModel(queryComboBoxModel);
    }

    private Vector<String> columnNames() {
        Vector<String> columnNames = new Vector<>();
        columnNames.addElement("员工编号");
        columnNames.addElement("员工姓名");
        columnNames.addElement("员工所属部门");
        columnNames.addElement("员工性别");
        columnNames.addElement("员工电话");
        return columnNames;
    }

    private Vector<Vector<Object>> getRowsData(int employeeId) throws SQLException {
        Employee employee = employeeDAO.selectById(employeeId);
        Vector<Vector<Object>> rowsData = new Vector<>();
        if (Objects.nonNull(employee)) {
            addRowToRows(rowsData, employee);
        }
        return rowsData;
    }

    private Vector<Vector<Object>> getRowsData(String keyword, int departmentId) throws SQLException {
        Vector<Employee> employees = employeeDAO.selectByKeyword(keyword, departmentId);
        Vector<Vector<Object>> rowsData = new Vector<>();
        for (Employee employee : employees) {
            addRowToRows(rowsData, employee);
        }
        return rowsData;
    }

    private void addRowToRows(Vector<Vector<Object>> rowsData, Employee employee) {
        Vector<Object> rowData = new Vector<>();
        rowData.addElement(employee.getEmployeeId());
        rowData.addElement(employee.getEmployeeName());
        rowData.addElement(employee.getDepartmentName());
        rowData.addElement(employee.getSex());
        rowData.addElement(employee.getTelephone());
        rowsData.addElement(rowData);
    }
}
